//
//  FileTranscriptionViewController.swift
//  SpeechAnalyzerDemo
//
//  UIKit 文件转写流程的实现。
//

import UIKit
import Combine
import UniformTypeIdentifiers

final class FileTranscriptionViewController: UIViewController {

    private let manager: SpeechAnalyzeManager
    private var cancellables = Set<AnyCancellable>()

    private let instructionsLabel = UILabel()
    private let fileNameLabel = UILabel()
    private let selectFileButton = UIButton(type: .system)
    private let transcribeButton = UIButton(type: .system)
    private let stopButton = UIButton(type: .system)
    private let transcriptsView = TranscriptionView()

    private var selectedFileURL: URL? {
        didSet {
            updateFileName()
            updateButtons(isTranscribing: manager.isTranscribing, isSettingUp: manager.isSettingUp)
        }
    }

    init(manager: SpeechAnalyzeManager) {
        self.manager = manager
        super.init(nibName: nil, bundle: nil)
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        title = "From File"
        view.backgroundColor = .systemBackground

        setupLayout()
        configureUI()
        bindManager()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        guard isMovingFromParent else { return }
        manager.resetTranscripts()
        Task {
            do {
                try await manager.stopTranscription()
            } catch {
                manager.error = error
            }
        }
    }
}

    // MARK: - 界面布局
private extension FileTranscriptionViewController {
    func setupLayout() {
        let stack = UIStackView()
        stack.axis = .vertical
        stack.spacing = 24
        stack.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(stack)

        NSLayoutConstraint.activate([
            stack.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            stack.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            stack.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 24)
        ])

        stack.addArrangedSubview(instructionsLabel)

        let fileRow = UIStackView()
        fileRow.axis = .horizontal
        fileRow.spacing = 12
        fileRow.alignment = .center
        fileNameLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
        selectFileButton.setContentHuggingPriority(.required, for: .horizontal)
        fileRow.addArrangedSubview(fileNameLabel)
        fileRow.addArrangedSubview(selectFileButton)
        stack.addArrangedSubview(fileRow)

        transcribeButton.heightAnchor.constraint(equalToConstant: 44).isActive = true
        stopButton.heightAnchor.constraint(equalToConstant: 44).isActive = true

        stack.addArrangedSubview(transcribeButton)
        stack.addArrangedSubview(stopButton)
        stack.addArrangedSubview(transcriptsView)
    }

    func configureUI() {
        instructionsLabel.numberOfLines = 0
        instructionsLabel.textColor = .secondaryLabel
        instructionsLabel.font = .preferredFont(forTextStyle: .body)
        instructionsLabel.text = "- Select an Audio File\n- Transcribe the Contents"

        fileNameLabel.font = .preferredFont(forTextStyle: .subheadline)
        fileNameLabel.textColor = .secondaryLabel
        fileNameLabel.numberOfLines = 1
        updateFileName()

        selectFileButton.setImage(UIImage(systemName: "plus.app"), for: .normal)
        selectFileButton.tintColor = .systemBlue
        selectFileButton.addTarget(self, action: #selector(selectFile), for: .touchUpInside)

        transcribeButton.setTitle("Load & Transcribe", for: .normal)
        transcribeButton.setTitleColor(.white, for: .normal)
        transcribeButton.setTitleColor(.white.withAlphaComponent(0.4), for: .disabled)
        transcribeButton.backgroundColor = .systemBlue
        transcribeButton.layer.cornerRadius = 8
        transcribeButton.addTarget(self, action: #selector(startTranscription), for: .touchUpInside)

        stopButton.setTitle("Stop Transcription", for: .normal)
        stopButton.setTitleColor(.white, for: .normal)
        stopButton.setTitleColor(.white.withAlphaComponent(0.4), for: .disabled)
        stopButton.backgroundColor = .systemRed
        stopButton.layer.cornerRadius = 8
        stopButton.addTarget(self, action: #selector(stopTranscriptionTapped), for: .touchUpInside)
    }
}

    // MARK: - 数据绑定
private extension FileTranscriptionViewController {
    func bindManager() {
        manager.$volatileTranscript
            .combineLatest(manager.$finalizedTranscript, manager.$transcriptionConfidence)
            .receive(on: RunLoop.main)
            .sink { [weak self] volatile, finalized, confidence in
                self?.transcriptsView.update(finalized: finalized, volatile: volatile, confidence: confidence)
            }
            .store(in: &cancellables)

        manager.$isTranscribing
            .combineLatest(manager.$isSettingUp)
            .receive(on: RunLoop.main)
            .sink { [weak self] isTranscribing, isSettingUp in
                self?.updateButtons(isTranscribing: isTranscribing, isSettingUp: isSettingUp)
            }
            .store(in: &cancellables)

        manager.$showError
            .receive(on: RunLoop.main)
            .sink { [weak self] showError in
                guard
                    showError,
                    let self,
                    let error = self.manager.error
                else { return }
                self.presentError(message: error.message)
            }
            .store(in: &cancellables)
    }

    func updateButtons(isTranscribing: Bool, isSettingUp: Bool) {
        let disableTranscribe = selectedFileURL == nil || isTranscribing || isSettingUp
        transcribeButton.isEnabled = !disableTranscribe
        transcribeButton.backgroundColor = disableTranscribe ? .systemBlue.withAlphaComponent(0.4) : .systemBlue

        let disableStop = !isTranscribing
        stopButton.isEnabled = !disableStop
        stopButton.backgroundColor = disableStop ? .systemRed.withAlphaComponent(0.4) : .systemRed
    }
}

    // MARK: - 辅助方法
private extension FileTranscriptionViewController {
    func updateFileName() {
        if let url = selectedFileURL {
            fileNameLabel.text = url.lastPathComponent
        } else {
            fileNameLabel.text = "No file selected."
        }
    }

    func presentError(message: String) {
        let alert = UIAlertController(title: "Oops!", message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default) { [weak self] _ in
            self?.manager.showError = false
        })
        present(alert, animated: true, completion: nil)
    }
}

    // MARK: - 用户操作
private extension FileTranscriptionViewController {
    @objc func selectFile() {
        let controller = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.audio], asCopy: false)
        controller.delegate = self
        present(controller, animated: true, completion: nil)
    }

    @objc func startTranscription() {
        guard let url = selectedFileURL else { return }
        Task { [weak self] in
            guard let self else { return }
            do {
                try await self.manager.transcribeFile(url)
            } catch {
                self.manager.error = error
            }
        }
    }

    @objc func stopTranscriptionTapped() {
        Task { [weak self] in
            guard let self else { return }
            do {
                try await self.manager.stopTranscription()
            } catch {
                self.manager.error = error
            }
        }
    }
}

    // MARK: - UIDocumentPickerDelegate
extension FileTranscriptionViewController: UIDocumentPickerDelegate {
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        selectedFileURL = urls.first
    }

    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        // 保留当前选择即可，无需处理。
    }
}
